package com.travel.service.impl;


import com.travel.domain.entity.SeckillVoucher;
import com.travel.mapper.SeckillVoucherMapper;
import com.travel.service.SeckillVoucherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

/**
 * 秒杀优惠券服务实现类
 */
@Service
public class SeckillVoucherServiceImpl extends ServiceImpl<SeckillVoucherMapper, SeckillVoucher> implements SeckillVoucherService {

    @Autowired
    private SeckillVoucherMapper seckillVoucherMapper;

    /**
     * 秒杀操作，使用库存字段作为版本号
     * @param voucherId 秒杀优惠券ID
     * @param userId 用户ID
     * @return 是否秒杀成功
     */
    // 相比悲观锁，乐观锁在高并发场景下更适合秒杀等场景，因为它避免了线程阻塞，提高了系统的吞吐量。
    public boolean seckillVoucher(Long voucherId, Long userId) {
        // 获取秒杀优惠券信息
        SeckillVoucher seckillVoucher = seckillVoucherMapper.selectById(voucherId);
        if (seckillVoucher == null || seckillVoucher.getStock() <= 0) {
            // 如果秒杀券不存在或库存为0，秒杀失败
            return false;
        }

        // 使用库存字段作为乐观锁控制库存，判断 stock 是否一致
        UpdateWrapper<SeckillVoucher> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("voucher_id", voucherId)  // 确保更新的是指定的优惠券
                .eq("stock", seckillVoucher.getStock())  // 确保库存一致,不一致会导致当前线程的操作失败
                .gt("stock", 0)  // 库存大于0
                .set("stock", seckillVoucher.getStock() - 1);  // 库存减1

        // 执行更新操作
        int rows = seckillVoucherMapper.update(null, updateWrapper);

        // 如果更新的行数为0，表示库存已被其他线程修改或已经秒杀完毕
        return rows > 0;
    }
}
